package com.delivery.controller;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.delivery.config.WxPayConfig;
import com.delivery.constant.DeliveryConstantEnum;
import com.delivery.entity.DeliveryLog;
import com.delivery.entity.Order;
import com.delivery.entity.OrderCompensation;
import com.delivery.mapper.OrderCompensationMapper;
import com.delivery.mapper.OrderMapper;
import com.delivery.mapper.UserMapper;
import com.delivery.service.DeliveryLogService;
import com.delivery.utils.WxMiniPayUtils;
import com.delivery.vo.CallbackUrlVo;
import com.kuaidi100.sdk.response.SubscribeResp;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@RestController
@RequestMapping("/kuaidi100")
public class Kuaidi100CallbackController {

    /**
     * 修改重量回调
     * @return
     */
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderCompensationMapper orderCompensationMapper;
    @Autowired
    DeliveryLogService deliveryLogService;

    @Autowired
    UserMapper userMapper;

    @Resource(name = "taskExecutor")
    Executor executor;

    @Value("${constant.commission}")
    private String commission;

    @Autowired
    WxPayConfig wxPayConfig;

    @Value("${wx.mini.secret}")
    private String secret;

    @PostMapping("/callbackUrl")
    @ApiOperation(value = "快递100平台回调地址")
    public SubscribeResp callbackUrl(String taskId, String sign, String param)   {
        System.out.println("param = " + param);

        CallbackUrlVo.Param resParam = JSON.parseObject(param, CallbackUrlVo.Param.class);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<Order>().eq(Order::getKuaidi100Id, resParam.getData().getOrderId());
        Order orderDb = orderMapper.selectOne(wrapper);

  //      String ourSign = SignUtils.sign(orderDb.getSign()  );

        //记录回调日志
        DeliveryLog deliveryLog = new DeliveryLog();
        deliveryLog.setLogKuaidi100Callbackurl(param);
        deliveryLogService.save(deliveryLog);


//     if (ourSign.equals(sign)){
            //与填写重量不一

        if ( resParam.getData().getStatus() .equals("15") ){

                //实际扣费大于预扣费
                if (orderDb.getOrderAmountWithhold().compareTo(new BigDecimal(resParam.getData().getFreight())) == -1){
                    LambdaQueryWrapper LambdaQueryWrapper = new LambdaQueryWrapper<OrderCompensation>().eq(OrderCompensation::getKuaidi100Id,resParam.getData().getOrderId() );

                    //当数据库没有补缴记录时插入数据
                    if (orderCompensationMapper.selectOne(LambdaQueryWrapper) == null){
                        //折后运费，单位：元
                        OrderCompensation orderCompensation = new OrderCompensation();          //创建补偿对象
                        orderCompensation.setOrderId(orderDb.getId());                         //赋值订单号
                        orderCompensation.setKuaidi100Id(resParam.getData().getOrderId());     //赋值快递100订单号
                        orderCompensation.setWeight(resParam.getData().getWeight());            //实际重量
                        orderCompensation.setVolume(resParam.getData().getVolume());            //实际体积
                        orderCompensation.setFreight(new BigDecimal(resParam.getData().getFreight())); //最终金额
                        orderCompensation.setPayStatus(DeliveryConstantEnum.StatusEnum.unpaid.getStatus());  //设置状态
                        orderCompensation.setOrderAmount(                                                      //设置订单价格
                                new BigDecimal(resParam.getData().getFreight())
                                        .multiply(new BigDecimal( commission )).setScale(1, BigDecimal.ROUND_HALF_UP) );
                        //插入补偿记录至数据库
                        orderCompensationMapper.insert(orderCompensation);

                        //异步发送补缴费用模板通知
                        CompletableFuture.runAsync(()->{
                            JSONObject body = new JSONObject();
                            body.put("touser", userMapper.selectById(orderDb.getUserId()).getOpenId() );
                            body.put("template_id","DtvnhjivdjslB6cChQ5N7odp33mG3aQ2Mp0S9TrR5-Q");
                            cn.hutool.json.JSONObject json = new cn.hutool.json.JSONObject();
                            json.set("character_string7",new cn.hutool.json.JSONObject().set("value",orderDb.getKuaidinum()));
                            BigDecimal subtract = orderCompensation.getOrderAmount().subtract(orderDb.getOrderAmount());
                            json.set("amount2",new cn.hutool.json.JSONObject().set("value", subtract.toString() + "元" ) );
                            json.set("thing6",new cn.hutool.json.JSONObject().set("value","寄件超重补缴"));
                            json.set("thing5",new cn.hutool.json.JSONObject().set("value","感谢您的使用，如有疑问请联系客服"));
                            body.put("data",json);
                            //发送
                            String accessToken = getAccessToken();
                            String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken, body.toString());

                            },executor);

                    }

                }else {

                    //实际扣费小于预扣费 退钱
                    CompletableFuture.runAsync(() -> {

                        JSONObject domesticRefundsJSON = new JSONObject();
                        domesticRefundsJSON.put("transaction_id", orderDb.getTransactionId());
                        //雪花算法生成退款订单号
                        String outRefundNo = new Snowflake().nextIdStr();
                        domesticRefundsJSON.put("out_refund_no", outRefundNo);
                        domesticRefundsJSON.put("reason", "快递下单支付费用大于实扣费用 退差价");
                        JSONObject amount = new JSONObject();

                        BigDecimal bigDecimal = new BigDecimal(resParam.getData().getFreight()).multiply(new BigDecimal(commission)).setScale(1, BigDecimal.ROUND_HALF_UP);
                        BigDecimal subtract = orderDb.getOrderAmount().subtract(bigDecimal);

                        amount.put("refund", (subtract.multiply(new BigDecimal("100"))).intValue());
                        amount.put("total", (orderDb.getOrderAmount().multiply(new BigDecimal("100"))).intValue());
                        amount.put("currency", "CNY");
                        domesticRefundsJSON.put("amount", amount);
                        domesticRefundsJSON.put("notify_url", wxPayConfig.getRefundsNotifyDomain());
                        String parm = domesticRefundsJSON.toJSONString();
                        String domesticRefundsBody = null;
                        try {
                            domesticRefundsBody = WxMiniPayUtils.v3Post("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds", parm);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                        //  JSONObject domesticRefundsBodyJSON = JSON.parseObject(domesticRefundsBody);

                    }, executor);


                    Order order = new Order();
                    order.setId(orderDb.getId());
                    //更新数据库订单数据
                    order.setOrderAmountWithhold( new BigDecimal(resParam.getData().getFreight()) );
                    order.setOrderAmount(
                            new BigDecimal(resParam.getData().getFreight()).multiply(new BigDecimal(commission )).setScale(1, BigDecimal.ROUND_HALF_UP)
                    );
                    orderMapper.updateById(order);

                }

            }



        //接单时 发送接单通知
        if ( resParam.getData().getStatus() .equals("1") ){

            CompletableFuture.runAsync(()->{
                JSONObject body = new JSONObject();
                body.put("touser", userMapper.selectById(orderDb.getUserId()).getOpenId() );
                body.put("template_id","uZ7if-HYKsW4ipFM64Q-0_8fkf966zuy3CJUtQSqdQI");
                cn.hutool.json.JSONObject json = new cn.hutool.json.JSONObject();
                json.set("name13",new cn.hutool.json.JSONObject().set("value",resParam.getData().getCourierName()));
                json.set("phone_number15",new cn.hutool.json.JSONObject().set("value", resParam.getData().getCourierMobile() ) );
                json.set("amount8",new cn.hutool.json.JSONObject().set("value", orderDb.getOrderAmount().toString() + "元" ));
                json.set("character_string19",new cn.hutool.json.JSONObject().set("value", orderDb.getKuaidinum() ));
                json.set("thing5",new cn.hutool.json.JSONObject().set("value", "请与快递员沟通取件时间或自行送到对应驿站") );
                body.put("data",json);
                //发送
                String accessToken = getAccessToken();
                String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken, body.toString());
                System.out.println("post = " + post);
            },executor);

        }


            if (orderDb!=null ){
                //更新订单状态
                Order order = new Order();
                order.setId(orderDb.getId());
                order.setOrderStatus(Integer.valueOf(resParam.getData().getStatus()));
                orderMapper.updateById(order);
            }



            //回应回调响应

            SubscribeResp subscribeResp = new SubscribeResp();
            subscribeResp.setResult(Boolean.TRUE);
            subscribeResp.setReturnCode("200");
            subscribeResp.setMessage("成功");
            return subscribeResp;

    }


    public String getAccessToken() {
        String appId = wxPayConfig.getAppid();
        String appSecret = secret;
        String result = cn.hutool.http.HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret);
        cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(result);
        return jsonObject.getStr("access_token");
    }




}
